#include<cstdio>
#include<cstring>
#define MAXN 400010
#define LL long long
LL MOD,sumv[MAXN],addv[MAXN],mulv[MAXN];
int n,m,t1,y1,y2,v;
void maintain(int o,int len)
{
	int lc=o<<1,rc=(o<<1)+1,M=len>>1;
	if(mulv[o]!=1||addv[o])
	{
		mulv[lc]=(mulv[lc]*mulv[o])%MOD;
		mulv[rc]=(mulv[rc]*mulv[o])%MOD;
		addv[lc]=((addv[lc]*mulv[o])+addv[o])%MOD;
		addv[rc]=((addv[rc]*mulv[o])+addv[o])%MOD;
		sumv[lc]=(sumv[lc]*mulv[o]+(len-M)*addv[o])%MOD;
		sumv[rc]=(sumv[rc]*mulv[o]+M*addv[o])%MOD;
	}
	addv[o]=0;
	mulv[o]=1;
}
void build(int o,int L,int R)
{
	int lc=o<<1,rc=(o<<1)+1,M=(L+R)/2;
	if(L==R)
	{
		scanf("%lld",&sumv[o]);
		return;
	}
	build(lc,L,M);
	build(rc,M+1,R);
	sumv[o]=(sumv[lc]+sumv[rc])%MOD;
}
void update(int o,int L,int R)
{
	int lc=o<<1,rc=(o<<1)+1,M=(L+R)/2;
	if(y1<=L&&y2>=R)
	{
		if(t1==1)
		{
			addv[o]=(addv[o]*v)%MOD;
			sumv[o]=(sumv[o]*v)%MOD;
			mulv[o]=(mulv[o]*v)%MOD;
		}
		else
		{
			addv[o]=(addv[o]+v)%MOD;
			sumv[o]=(sumv[o]+v*(R-L+1))%MOD;
		}
		return;
	}
	maintain(o,R-L+1);
	if(y1<=M)update(lc,L,M);
	if(y2>M)update(rc,M+1,R);
	sumv[o]=(sumv[lc]+sumv[rc])%MOD;
}
LL query(int o,int L,int R)
{
	int lc=o<<1,rc=(o<<1)+1,M=(L+R)>>1;
	if(y1<=L&&y2>=R)return sumv[o]%MOD;
	maintain(o,R-L+1);
	LL ans=0;
	if(y1<=M)ans=(query(lc,L,M))%MOD;
	if(y2>M)ans+=(query(rc,M+1,R))%MOD;
	sumv[o]=(sumv[lc]+sumv[rc])%MOD;
	return ans%MOD;
}
int main()
{
	scanf("%d%lld",&n,&MOD);
	for(int i=1;i<=400009;i++)mulv[i]=1;
	build(1,1,n);
	scanf("%d",&m);
	while(m--)
	{
		scanf("%d%d%d",&t1,&y1,&y2);
		if(t1!=3)
		{
			scanf("%d",&v);
			update(1,1,n);
		}
		else printf("%lld\n",query(1,1,n));
	}
	return 0;
}
